<?php

declare(strict_types=1);

namespace app\admin\service;

use app\common\enum\SysEnum;
use think\facade\Db;

/**
 * 系统日志
 */
class SystemLoggerService
{
    private string $level;

    private string $module;

    /**
     * @param string $msg
     * @param array ...$argc
     */
    public function write(string $msg, ...$argc): void
    {
        $this->writeLog($msg, $argc);
    }
    /**
     * @param string $msg
     * @param array ...$argc
     */
    public function notice(string $msg, ...$argc): void
    {
        array_unshift($argc, 'notice');
        $this->writeLog($msg, $argc);
    }
    /**
     * @param string $msg
     * @param array ...$argc
     */
    public function error(string $msg, ...$argc): void
    {
        array_unshift($argc, 'error');
        $this->writeLog($msg, $argc);
    }
    /**
     * @param string $msg
     * @param array ...$argc
     */
    public function warning(string $msg, ...$argc): void
    {
        array_unshift($argc, 'warning');
        $this->writeLog($msg, $argc);
    }
    /**
     * 日志
     * @param string $level 日志等级
     * @param string $message 日志信息
     * @param string $module 日志模块
     * @param array $param 操作数据
     * @param string $tag 错误标识
     */
    public function log(string $level, string $message, string $module = '', array $param = [], string $tag = ''): void
    {
        $this->setLevel($level);
        $this->setModule($module);
        $this->saveLog($message, $param, $tag);
    }
    /**
     * @param string $grade
     */
    private function setLevel(string $level)
    {
        $level = $level ?: 'notice';
        if (!in_array($level, ['notice', 'error', 'warning'])) {
            tips('只支持 notice、error、warning类型日志');
        }
        $this->level = $level;
    }
    /**
     * @param string $module
     */
    private function setModule(string $module)
    {
        $this->module = $module ?: 'default';
    }
    /**
     * @param string $message
     * @param array $argc
     */
    private function writeLog(string $message, $argc)
    {
        $level = $argc[0] ?? ''; // 等级
        $module = $argc[1] ?? ''; // 模块
        $param = $argc[2] ?? []; // 操作数据
        $tag = $argc[3] ?? ''; // 错误标识
        if (!is_array($param)) {
            $param = [];
        }
        $this->setLevel($level);
        $this->setModule($module);
        $this->saveLog($message, $param, $tag);
    }
    /**
     * 保存日志
     */
    private function saveLog(string $message, array $param, string $tag)
    {
        $request = request();
        if (!$param) {
            $param = $request->param() ?? [];
        }
        $port = $request->port ?? SysEnum::PORT_USER;
        $log = [
            'module' => $this->module,
            'level' => $this->level,
            'message' => $message,
            'param' => json_encode($param, JSON_UNESCAPED_UNICODE),
            'tag' => $tag,
            'router' => $request->baseUrl() ?? '',
            'method' => $port ? $request->method() : '',
            'uid' => $request->uid ?? SysEnum::DEVELOPER,
            'port' => $port,
            'created_at' => date('Y-m-d H:i:s'),
            'time_stamp' => time(),
        ];
        Db::name('system_logger')->insert($log);
    }
}
